#ifndef _PROCESS_POOL_HPP_
#define _PROCESS_POOL_HPP_

#include"task.hpp"

#include<iostream>
#include<vector>
#include<unistd.h>
#include<sys/wait.h>
using namespace std;

const int gdefaultn=5;

class Channel
{
public:
    Channel(int wfd,int subid)
    :_wfd(wfd)
    ,_subid(subid)
    {
        _name="channel-"+to_string(wfd)+"-"+to_string(subid);
    }
    void send(int code)
    {
        int n=write(_wfd,&code,sizeof(code));
        (void)n;
    }

    void Close()
    {
        close(_wfd);
    }
    void Wait()
    {
        int wid=waitpid(_subid,nullptr,0);
        (void)wid;
    }
    int Fd(){return _wfd;}
    pid_t Subid(){return _subid;}
    string Name(){return _name;}
    ~Channel(){}
private:
    int _wfd;
    pid_t _subid;
    string _name;
};

class ChannelManage
{
public:
    ChannelManage():
    _next(0)
    {}

    void BuildChannel(int wfd,int subid)
    {
        _channels.emplace_back(wfd,subid);
    }

    Channel& select()
    {
        auto &c=_channels[_next];
        _next++;
        _next%=_channels.size();
        return c;
    }
    void printfchannel()
    {
        for(auto &ch:_channels)
        {
            cout<<ch.Name()<<endl;

        }
    }
    //子进程所需要的运行关闭从父进程继承下来的写端
    //写时拷贝发生
    void closeAll()
    {
        for(auto& c:_channels)
        {
            c.Close();
        }
    }
    void stopSubProcess()
    {
        for(auto& c:_channels)
        {
            c.Close();
            cout<<"关闭："<<c.Name()<<endl;
        }
    }
    void WaitSubProcess()
    {
        for(auto& c:_channels)
        {
            c.Wait();
            cout<<"回收："<<c.Subid()<<endl;
        }
    }
    ~ChannelManage(){}
private:
    vector<Channel> _channels;
    int _next;

};


class ProcessPool
{
public:
    ProcessPool(int num)
    :_process_num(num)
    {
        _tm.Register(printLog);
        _tm.Register(Downlode);
        _tm.Register(uplode);

    }
    void work(int rfd)
    {
        while(true)
        {

            int code=0;
            ssize_t n=read(rfd,&code,sizeof(code));
            if(n>0)
            {
                if(n!=sizeof(code))
                {
                    continue;
                }
                cout<<"子进程["<<getpid()<<"]收到一个任务码"<<code<<endl;
                _tm.Execute(code);
            }
            else if(n==0)
            {
                break;
            }
            else
            {
                cout<<"read error"<<endl;
            }
        }
    }
    bool create()
    {
        for(int i=0;i<_process_num;i++)
        {
            //创建管道
            int pipefd[2];
            int n=pipe(pipefd);
            if(n<0) { return false; }
            //创建进程
            //关闭不需要的文件描述符，形成单向信道
            pid_t subid=fork();
            if(subid<0){return false;}
            else if(subid==0)
            {
                //子进程
                _cm.closeAll();
                close(pipefd[1]);
                work(pipefd[0]);
                close(pipefd[0]);
                exit(0);
            }
            else
            {
                close(pipefd[0]);
                //父进程
                _cm.BuildChannel(pipefd[1],subid);
            }

        }
        return true;
    }
    void debug()
    {
        _cm.printfchannel();
    }
    void Run()
    {
        int taskcode=_tm.code();
        auto& c=_cm.select();  
        cout<<"选择了一个子进程"<<c.Name()<<endl;
        cout<<"发送了一个任务码"<<taskcode<<endl;
        c.send(taskcode);
       
    }
    void stop()
    {
        _cm.stopSubProcess();
        _cm.WaitSubProcess();

    }
 
    ~ProcessPool(){}
private:
    ChannelManage _cm;
    int _process_num;

    taskManage _tm;
};





#endif